﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MMSA.Services.SharedServices;
using SmartProcess.Core.Commons.Tracing;

namespace MMSA.Services.Services
{
    public class PlaceManagementService : IDataManagementService
    {
        private TracingService tracing = new TracingService("MMSA.Services");
        string traceServicio = string.Empty;
        public void MassiveProductUpload(string fileName, string fileExtension)
        {
            try
            {
                var dataTable = new DataTable("RUT_LOCAL");

                traceServicio = "Antes de cargar desde archivo excel: " + fileName;

                dataTable.GetDataFromExcelSpreadsheet(fileName, fileExtension);
                MMSA.Entities.Local.RUT_LOCALDataTable local = new Entities.Local.RUT_LOCALDataTable();

                traceServicio = "Antes de recorrer las columnas de lugares";

                foreach (DataRow item in dataTable.Rows)
                {
                    var row = local.NewRUT_LOCALRow();
                    for (int i = 0; i < dataTable.Columns.Count; i++)
                    {
                        Boolean flag = true;
                        traceServicio = "Se cayo al leer la Columna: " + dataTable.Columns[i].ColumnName + " ,revise si el archivo subido pertenece al formato correcto.";
                        if (dataTable.Columns[i].ColumnName.Equals("loc_estado") || dataTable.Columns[i].ColumnName.Equals("loc_nuevo"))
                        {
                            if (item[dataTable.Columns[i].ColumnName].Equals(1.0))
                            {
                                row[dataTable.Columns[i].ColumnName] = Convert.ChangeType(true,
                              local.Columns[dataTable.Columns[1].ColumnName].DataType);
                                flag = false;
                            }
                            else
                            {
                                if (item[dataTable.Columns[i].ColumnName].Equals("NULL"))
                                {
                                    flag = false;
                                    row[dataTable.Columns[i].ColumnName] = Convert.ChangeType(false,
                                    local.Columns[dataTable.Columns[1].ColumnName].DataType);

                                }
                                else
                                {
                                    flag = false;
                                    row[dataTable.Columns[i].ColumnName] = Convert.ChangeType(false,
                                    local.Columns[dataTable.Columns[1].ColumnName].DataType);
                                }
                            }
                            
                        }
                        if (flag)
                        {
                            if (item[dataTable.Columns[i].ColumnName].Equals("NULL"))
                            {
                                if (dataTable.Columns[i].ColumnName.Equals("loc_longitud") ||
                                    dataTable.Columns[i].ColumnName.Equals("loc_latitud")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_cupo")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_per_id")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_fre_id")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_id_usuario")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_id_orden")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_cupo")||
                                    dataTable.Columns[i].ColumnName.Equals("loc_plazo")||
                                    dataTable.Columns[i].ColumnName.Equals("lst_id"))
                                {
                                    row[dataTable.Columns[i].ColumnName] = Convert.ChangeType(0,
                               local.Columns[dataTable.Columns[2].ColumnName].DataType);

                                }
                                else
                                {

                                    row[dataTable.Columns[i].ColumnName] = Convert.ChangeType("",
                                 local.Columns[dataTable.Columns[2].ColumnName].DataType);

                                }
                                
                            }
                            else
                            {
                                row[dataTable.Columns[i].ColumnName] = Convert.ChangeType(item[dataTable.Columns[i].ColumnName],
                                local.Columns[dataTable.Columns[2].ColumnName].DataType);

                            }
                        }



                    }
                    local.AddRUT_LOCALRow(row);
                }
                traceServicio = "Antes de generar el upsert de actualización e inserción.";
                string[] array = new string[1] { "loc_id" };
                string[] arrayExclude = new string[1] { "loc_id" };
                InsertOrUpdate(local);
                //local.Upsert("loc_id", useIdentityInsert: true, identityColumns: array, excludedUpdateColumns: arrayExclude);
            }
            catch (Exception exception)
            {
                if (exception != null)
                    tracing.ErrorFormat("MMSA.Services.Services.PlaceManagementService ==> TRACE: {0}, ==> ERROR: {1}, ==> STACKTRACE: {2}", traceServicio, exception.Message, exception.StackTrace);
                throw;
            }

        }
        private static Dictionary<Type, SqlDbType> typeReference;

        public static void loadDictionary()
        {
            typeReference = new Dictionary<Type, SqlDbType>();
            typeReference.Add(typeof(string), SqlDbType.NVarChar);
            typeReference.Add(typeof(Guid), SqlDbType.UniqueIdentifier);
            typeReference.Add(typeof(long), SqlDbType.BigInt);
            typeReference.Add(typeof(byte[]), SqlDbType.Binary);
            typeReference.Add(typeof(bool), SqlDbType.Bit);
            typeReference.Add(typeof(DateTime), SqlDbType.DateTime);
            typeReference.Add(typeof(decimal), SqlDbType.Decimal);
            typeReference.Add(typeof(double), SqlDbType.Float);
            typeReference.Add(typeof(int), SqlDbType.Int);
            typeReference.Add(typeof(float), SqlDbType.Real);
            typeReference.Add(typeof(short), SqlDbType.SmallInt);
            typeReference.Add(typeof(byte), SqlDbType.TinyInt);
            typeReference.Add(typeof(object), SqlDbType.Udt);
            typeReference.Add(typeof(DataTable), SqlDbType.Structured);
            typeReference.Add(typeof(DateTimeOffset), SqlDbType.DateTimeOffset);

        }

        public void InsertOrUpdate(DataTable data)
        {
            loadDictionary();
            var conection = ConfigurationManager.AppSettings["conection"];
            SqlConnection conn = new SqlConnection(conection);
            conn.Open();
            foreach (DataRow row in data.Rows)
            {
                var query = GetInsertOrUpdateString((int)row["loc_id"] > 0);
                var command = new SqlCommand(query, conn);

                foreach (DataColumn column in data.Columns)
                {
                    var param = new SqlParameter(column.ColumnName.Replace('/', '_'), typeReference[column.DataType]);
                    param.Value = row[column.ColumnName];
                    command.Parameters.Add(param);
                }
                command.ExecuteNonQuery();
                
            }
            conn.Close();
        }

        public string GetInsertOrUpdateString(bool insertIdentity = false)
        {

            var identityInsertOn = " SET IDENTITY_INSERT RUT_LOCAL ON; ";
            var identityInsertOff = " SET IDENTITY_INSERT RUT_LOCAL OFF; ";
            var query = ((insertIdentity) ? identityInsertOn : String.Empty) + @" IF NOT EXISTS (SELECT * FROM RUT_LOCAL 
                   WHERE loc_id = @loc_id)
                BEGIN " +
                    @"INSERT INTO RUT_LOCAL (" + ((insertIdentity) ? "loc_id," : string.Empty) + @"loc_nombre, loc_direccion, loc_referencia, loc_pais, loc_provincia, loc_ciudad, loc_foto, loc_ruc, "
                    + @"loc_telefono1, loc_telefono2,[loc_tipo/canal], loc_estado, loc_longitud, loc_latitud, loc_per_id, loc_fre_id, loc_id_usuario, loc_id_orden, loc_id_cod1,loc_id_cod2,loc_id_cod3,loc_id_cod4, frecuencia, loc_cupo, loc_plazo, lst_id, loc_nuevo)
                    VALUES(" + ((insertIdentity) ? "@loc_id," : string.Empty) + @"@loc_nombre,@loc_direccion,@loc_referencia,@loc_pais,@loc_provincia,@loc_ciudad,@loc_foto,@loc_ruc,@loc_telefono1,@loc_telefono2,@loc_tipo_canal,@loc_estado,@loc_longitud,@loc_latitud,@loc_per_id,@loc_fre_id,@loc_id_usuario,@loc_id_orden,@loc_id_cod1,@loc_id_cod2,@loc_id_cod3,@loc_id_cod4,@frecuencia,@loc_cupo,@loc_plazo,@lst_id,@loc_nuevo)"

                    +
                    @"END
                ELSE
                BEGIN
                    UPDATE RUT_LOCAL
                    SET loc_nombre=@loc_nombre,loc_direccion=@loc_direccion,loc_referencia=@loc_referencia,loc_pais=@loc_pais,loc_provincia=@loc_provincia,loc_ciudad=@loc_ciudad,loc_foto=@loc_foto,loc_ruc=@loc_ruc,loc_telefono1=@loc_telefono1,loc_telefono2=@loc_telefono2,[loc_tipo/canal]=@loc_tipo_canal,loc_estado=@loc_estado,loc_longitud=@loc_longitud,loc_latitud=@loc_latitud,loc_per_id=@loc_per_id,loc_fre_id=@loc_fre_id,loc_id_usuario=@loc_id_usuario,loc_id_orden=@loc_id_orden,loc_id_cod1=@loc_id_cod1,loc_id_cod2=@loc_id_cod2,loc_id_cod3=@loc_id_cod3,loc_id_cod4=@loc_id_cod4,frecuencia=@frecuencia,loc_cupo=@loc_cupo,loc_plazo=@loc_plazo,lst_id=@lst_id,loc_nuevo=@loc_nuevo
                    WHERE  loc_id = @loc_id
                END" + ((insertIdentity) ? identityInsertOff : String.Empty);
            return query;
        }
    }
}
